package com.lzc.fileserver.file.controller;


import com.lzc.fileserver.common.util.ResultVOUtil;
import com.lzc.fileserver.common.vo.ResultVo;
import com.lzc.fileserver.file.dataobject.File;
import com.lzc.fileserver.file.service.FileService;
import com.lzc.fileserver.file.util.MD5Util;

import org.bson.types.Binary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Controller
@CrossOrigin
@RequestMapping("/file")
public class FileController {

    @Value("${server.address}")
    private String serverAddress;

    @Value("${server.port}")
    private String serverPort;

    @Autowired
    private FileService fileService;

    // ####################################################################################################
    @RequestMapping(value = "/files")
    @ResponseBody
    public Object fileList(@RequestParam(name = "pageNum", defaultValue = "1")Integer pageNum,
                             @RequestParam(name = "pageSize", defaultValue = "10")Integer pageSize) {
        Page<File> page = fileService.listByPage(pageNum-1, pageSize);

        Map<String, Object> data = new HashMap<>();
        data.put("list",page.getContent());
        data.put("total",page.getTotalElements());
        data.put("errorNo",0);
        data.put("data",page.getContent());

        return data;
    }
    /**
     * 上传接口
     *
     * @param file
     * @return
     */
    @PostMapping("/files")
    @ResponseBody
    public Object handleFileUpload(@RequestParam("file") MultipartFile file) {
        File returnFile = null;
        try {
            File f = new File(file.getOriginalFilename(), file.getContentType(), file.getSize(),
                    new Binary(file.getBytes()));
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            returnFile = fileService.saveFile(f);
            //String path = "http://localhost:8081/file/files/view/" + returnFile.getId();
            String path = "http://" + serverAddress + ":" + serverPort + "/file/files/view/" + returnFile.getId();
            return ResultVOUtil.success(path);
        } catch (Exception e) {
            return ResultVOUtil.error(-1, "文件上传异常：" + e.getMessage());
        }

    }
    /**
     * 删除文件
     *
     * @param id
     * @return
     */
    @DeleteMapping("/files/{id}")
    @ResponseBody
    public ResultVo deleteFile(@PathVariable String id) {
        try {
            fileService.removeFile(id);
            return ResultVOUtil.success();
        } catch (Exception e) {
            return ResultVOUtil.error(-1, "文件删除失败：" + e.getMessage());
        }
    }
    // ####################################################################################################

    @RequestMapping(value = "/index")
    public String fileindex(Model model) {
        // 展示最新二十条数据
        model.addAttribute("files", fileService.listFilesByPage(0, 20));
        return "file/index";
    }

    /**
     * 获取文件片信息
     *
     * @param id
     * @return
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/files/{id}")
    @ResponseBody
    public ResponseEntity<Object> serveFile(@PathVariable String id) throws UnsupportedEncodingException {

        Optional<File> file = fileService.getFileById(id);

        if (file.isPresent()) {
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; fileName=" + new String(file.get().getName().getBytes("utf-8"),"ISO-8859-1"))
                    .header(HttpHeaders.CONTENT_TYPE, "application/octet-stream")
                    .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize() + "").header("Connection", "close")
                    .body(file.get().getContent().getData());
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not fount");
        }

    }

    /**
     * 在线显示文件
     *
     * @param id
     * @return
     */
    @GetMapping("/files/view/{id}")
    @ResponseBody
    public ResponseEntity<Object> serveFileOnline(@PathVariable String id) {
        Optional<File> file = fileService.getFileById(id);

        if (file.isPresent()) {
            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\"" + file.get().getName() + "\"")
                    .header(HttpHeaders.CONTENT_TYPE, file.get().getContentType())
                    .header(HttpHeaders.CONTENT_LENGTH, file.get().getSize() + "").header("Connection", "close")
                    .body(file.get().getContent().getData());
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body("File was not fount");
        }

    }

    /**
     * 上传
     *
     * @param file
     * @param redirectAttributes
     * @return
     */
    @PostMapping("/upload")
    public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {
        try {
            File f = new File(file.getOriginalFilename(), file.getContentType(), file.getSize(),
                    new Binary(file.getBytes()));
            f.setMd5(MD5Util.getMD5(file.getInputStream()));
            fileService.saveFile(f);
        } catch (IOException | NoSuchAlgorithmException ex) {
            ex.printStackTrace();
            redirectAttributes.addFlashAttribute("message", "Your " + file.getOriginalFilename() + " is wrong!");
            return "redirect:/";
        }
        redirectAttributes.addFlashAttribute("message",
                "You successfully uploaded " + file.getOriginalFilename() + "!");
        return "redirect:/file/index";
    }



}
